package metainv;

import java.io.IOException;

import daikon.Daikon;
import daikon.PptRelation;
import daikon.VarInfo;
import daikon.chicory.VarKind;

public class MetaInv {
	//used in daikon.PptSliceEquality
	public static boolean equality = false;
	
	public static void main(String[] args) throws SecurityException, IOException, ClassNotFoundException, NoSuchMethodException {
		new MetaConstraintsIO().readInputFile(args[0]);
		//daikon.inv.filter.ParentFilter.dkconfig_enabled = false;
		String[] optionAndFile;
		//MetaInv.equality =  true;
		int sizeArgs = args.length;
		if(!MetaConstraintsIO.var_regexp.equals("")) {
//			optionAndFile = new String[2];
//			optionAndFile[0] = "--var-select-pattern=" + MetaConstraintsIO.var_regexp; 
//			optionAndFile[1] = args[1];
//			optionAndFile = new String[4];
//			optionAndFile[0] = "--var-select-pattern=" + MetaConstraintsIO.var_regexp; 
//			optionAndFile[1] = args[1];
//			optionAndFile[2] = args[2];
//			optionAndFile[3] = args[3];
			optionAndFile = new String[sizeArgs];
			optionAndFile[0] = "--var-select-pattern=" + MetaConstraintsIO.var_regexp;
			System.arraycopy(args, 1, optionAndFile, 1, sizeArgs);
		}
		else {
//			optionAndFile = new String[1];
//			optionAndFile[0] = args[1];
//			optionAndFile = new String[2];
//			optionAndFile[1] = args[1];
//			optionAndFile[0] = "--ppt-select-pattern=bidimap.TreeBidiMap";
//			optionAndFile = new String[3];
//			optionAndFile[0] = "--disc_reason";
//			optionAndFile[1] = "all";
//			optionAndFile[2] = args[1];
//			optionAndFile = new String[5];
//			optionAndFile[0] = "--disc_reason";
//			optionAndFile[1] = "all";
//			optionAndFile[2] = args[1];
//			optionAndFile[3] = args[2];
//			optionAndFile[4] = args[3];
			 
//			optionAndFile = new String[4];
//			optionAndFile[0] = "--suppress_redundant";
//			optionAndFile[1] = "--ppt-omit-pattern=StackArTester";
//			optionAndFile[2] = args[1];
//			optionAndFile[3] = args[2];
			
//			optionAndFile = new String[3];
//			optionAndFile[0] = "--suppress_redundant"; 
//			optionAndFile[1] = "--ppt-omit-pattern=Test";
//			optionAndFile[2] = args[1];
			optionAndFile = new String[sizeArgs-1];
			System.arraycopy(args, 1, optionAndFile, 0, sizeArgs-1);
			
		}
		Daikon.main(optionAndFile);
	}
	
	public static boolean compareField(VarInfo va, VarInfo vb) {
		//parameternames[..].toString would be equal to this.filename.toString without this step
		if(!va.type.equals(vb.type))
			return false;
		
		String nameA, nameB;
		int dotA, dotB;
		String simpleNameA, simpleNameB;
		String enclosingNameA, enclosingNameB;
		//name.toString would be equal to this.filename.toString without the following step
		if(va.var_kind.equals(VarInfo.VarKind.FUNCTION) && va.var_kind.equals(VarInfo.VarKind.FUNCTION) && va.enclosing_var!=null && vb.enclosing_var != null) {
			enclosingNameA = va.enclosing_var.name();
			enclosingNameB = vb.enclosing_var.name();
			dotA = enclosingNameA.lastIndexOf(".");
			dotB = enclosingNameB.lastIndexOf(".");
			if(dotA!=-1)
				simpleNameA = enclosingNameA.substring(dotA+1, enclosingNameA.length());
			else
				simpleNameA = enclosingNameA;
			
			if(dotB!=-1)
				simpleNameB = enclosingNameB.substring(dotB+1, enclosingNameB.length());
			else
				simpleNameB = enclosingNameB;
			
			if(!simpleNameA.equals(simpleNameB))
				return false;
		}
		else {
			nameA = va.name();
			nameB = vb.name();
			
			dotA = nameA.lastIndexOf(".");
			dotB = nameB.lastIndexOf(".");
			
			simpleNameA = nameA.substring(dotA+1, nameA.length());
			simpleNameB = nameB.substring(dotB+1, nameB.length());
			
			if(!simpleNameA.equals(simpleNameB))
				return false;
		}
		
		//disregard static variable, need change in the future
		if (va.enclosing_var == null || vb.enclosing_var == null) {
			if(va.str_name().equals(vb.str_name()))
				return true;
			else
				return false;
		}
		
		String enclosingTypeA = va.enclosing_var.type.base();
		String enclosingTypeB = vb.enclosing_var.type.base();
		
		if(!enclosingTypeA.equals(enclosingTypeB)) 
			return false;
		
		
		return true;
	}
	
	public static boolean compareParamSubrange(VarInfo va, VarInfo vb) {
		if(va.str_name().equals(vb.str_name()))
			return true;
		else
			return false;
	}

	public static boolean compareArrayAndFunction(VarInfo va, VarInfo vb) {
		if(va.str_name().equals(vb.str_name()))
			return true;
		else
			return false;
	}
	
	public static boolean comparevarInfoFunction(VarInfo va, VarInfo vb, PptRelation rel) {
		if(va.str_name().equals(vb.str_name())) {
			
			return true;
		}
		else {
			if(va.postState == null) {
				//			VarInfo vc = va.postState;
				VarInfo vae = va.enclosing_var;
				VarInfo vbe = vb.enclosing_var;
				
				while( vae != null && vbe != null && vae.var_kind.equals(vbe.var_kind)) {
					vae = vae.enclosing_var;
					vbe = vbe.enclosing_var;
				}
				
				if(va.isParam() && vb.isParam() && rel != null && (rel.parent_to_child_map.get(vb).equals(va)))// && !vc.name().equals("this"))
					return true;
			}
		}
		return false;
	}
	
	public static boolean comparevarInfoField(VarInfo va, VarInfo vb) {
		if(va.str_name().equals(vb.str_name())) {
			if(va.postState != null) {
				VarInfo vc = va.postState;
				while(vc.enclosing_var != null) {
					vc = vc.enclosing_var;
				}
				if(vc.isParam() && !vc.name().equals("this"))
					return false;
			}
			return true;
		}
		else
			return false;
	}
	
	public static boolean comparevarInfoVariable(VarInfo va, VarInfo vb) {
		if(va.str_name().equals(vb.str_name())) {
			if(va.postState != null) {
				VarInfo vc = va.postState;
				
				if(vc.isParam() || vc.is_field() || vc.var_kind.equals(VarKind.FUNCTION))
					return true;
				
			}
		}
		return false;
	}
}
